#include "manager.h"

FILE* rfp_borrow;

//菜单

void manager_menu(void)               //管理员菜单
{
    system("clear");
    puts("*****操作员系统*****");
	puts("1、图书管理");
	puts("2、图书借阅");
    puts("3、图书归还");
    puts("4、查看逾期记录");
	puts("5、返回上一级");
}

void manager_book_menu(void)               //管理员菜单
{
    system("clear");
    puts("*****操作员系统*****");
	puts("1、增加图书种类");
	puts("2、删除图书");
    puts("3、增加图书数量");
    puts("4、图书报损");
	puts("5、返回上一级");
}




//操作员系统
int login_manager(void)  //操作员登录
{
	system("clear");
	printf("请输入操作员ID\n");
	int id;
	scanf("%d",&id);
    getchar();
	printf("请输入密码\n");
	char password[20];
	get_passwd(password,sizeof(password));
    int index = query_operatorid(id);
    if(-1 == index || strcmp(operator[index].password,password))
    {
        print_sec("用户名或密码错误!",0.75);
        return -1;
    }
    return 0;
}

void manager(void) //管理员界面
{
	if(0 != login_manager())
	{
		return ;
	}
    rfp_borrow = fopen("borrow.txt","r");
    for(;;)
	{
		manager_menu();

		switch(get_cmd('1','5'))
		{
		case '1': manager_book();break;                     //管理书籍
		case '2': borrow_book() ;break;                     //借书
        case '3': repay_book()  ;break;                     //还书
        case '4': show_overdue();break;
		case '5': fclose(rfp_borrow);
        return;
		}
	}
}

void manager_book(void)
{
    load_book_index();
    for(;;)
	{
		manager_book_menu();
		switch(get_cmd('1','5'))
		{
		case '1': add_book()         ;break;                         //增加书籍
		case '2': delete_book()      ;break;                         //删除书籍
        case '3': add_sum_book()     ;break;                         //增加书籍数量
        case '4': loss_book()        ;break;                         //图书报损
        case '5': save_book_index();
        return;
		}
	}
}

void add_book(void)
{
    printf("请输入书号:(ISBN)\n");
    char ISBN[14];
    get_str(ISBN,sizeof(ISBN));
    if(13 != strlen(ISBN))
    {
        print_sec("书号位数错误!\n",0.75);
        return;
    }
    if(!bookfile_empty(ISBN))
    {
        print_sec("文件已存在!\n",0.75);
        return;
    }
    Book* book = malloc(sizeof(Book));
    strcpy(book->ISBN,ISBN);
    printf("请输入书名:\n");
    get_str(book->bookname,sizeof(book->bookname));
    printf("请输入首写字母:\n");
    while(1)
    {
        char key[2];
        get_str(key,sizeof(key));
        if(strlen(key) > 1)
        {
            printf("输入了过多位数");
            continue;
        }
        if(*key>='A' && *key<='Z')
        {
            book->key = *key-'A';
            break;
        }
        if(*key>='a' && *key<='z')
        {
            book->key = *key-'a';
            break;
        }
        printf("首写字母输入不符合规范,请重新输入!(a~z 或 A~Z)\n");
    }
    printf("请输入出版社:\n");
    get_str(book->publish,sizeof(book->publish));
    printf("请输入作者:\n");
    get_str(book->writer,sizeof(book->writer));
    printf("请输入书籍数量:\n");
    scanf("%u",&(book->book_sum));
    printf("请输入书籍价格:\n");
    scanf("%f",&(book->book_price));
    printf("请输入书籍类别:\n");
    puts("1.马克思主义");
    puts("2.哲学、宗教");
    puts("3.社会科学总论");
    puts("4.政治、法律");
    puts("5.经济");
    puts("6.文化、科学、教育、体育");
    puts("7.文学");
    puts("8.艺术");
    puts("9.历史、地理");
    puts("0.自然科学");
    
    switch(get_cmd('0','9'))
	{
        case '0':book->type = 0     ;break;
		case '1':book->type = 1     ;break;                         
		case '2':book->type = 2     ;break;                     
        case '3':book->type = 3     ;break;
        case '4':book->type = 4     ;break;
		case '5':book->type = 5     ;break;
        case '6':book->type = 6     ;break;
        case '7':book->type = 7     ;break;
        case '8':book->type = 8     ;break;
        case '9':book->type = 9     ;break;
	}
    book->book_borrowed = 0;
    book->book_ordered = 0;
    book->broken_manmade = 0;
    book->broken_aging = 0;
    write_book_msg(book);
    write_book_name(book->bookname,book->ISBN);
    add_book_key_index(book);
    add_book_type_index(book);
    free(book);
    print_sec("添加完成!\n",0.75);
}

void write_book_name(const char* book_name,const char* ISBN)
{
    FILE* afp = fopen("/home/coco/图书馆管理系统/book_data/book_name","a");
    fprintf(afp,"%s %s\n",book_name,ISBN);
    fclose(afp);
}

void delete_book(void)
{
    printf("请输入您要删除的书籍书号:\n");
    char ISBN[14];
    get_str(ISBN,sizeof(ISBN));
    if(13 != strlen(ISBN))
    {
        print_sec("书号输入错误!\n",0.75);
        return;
    }
    Book* book = read_book_msg(ISBN);
    if(NULL == book)
    {
        print_sec("没有该书号!\n",0.75);
        return;
    }
    char filename[18];
    strcpy(filename,ISBN);
    strcat(filename,".txt");
    char path[100] = "/home/coco/图书馆管理系统/book_data/";
    strcat(path,filename); 
    printf("确定删除?");
    if(yes_or_no())
    {
        if(0 == remove(path))
        {
            delete_all_order(ISBN);             //删除所有学生中有预约这本书的记录
            delete_book_key_index(book);
            delete_book_type_index(book);
            free(book);
            print_sec("删除成功!\n",0.75);
            return;
        }
    }
}

void add_sum_book(void)
{
    printf("请输入您要增加的书号:\n");
    char ISBN[14];
    get_str(ISBN,sizeof(ISBN));
    if(13 != strlen(ISBN))
    {
        print_sec("位数输入错误!\n",0.75);
        return;
    }
    Book* book = read_book_msg(ISBN);
    if(NULL == book)
    {
        print_sec("没有该书号!\n",0.75);
        return;
    }
    printf("书名:%s 作者:%s 出版社:%s\n",book->bookname,book->writer,book->publish);
    printf("总数:%u 价格%.2f 类型:%u 首字母:%u\n",book->book_sum,book->book_price,book->type,book->key);
    printf("出借:%u 预约:%u 自然损坏:%u 人为损坏:%u\n",book->book_borrowed,book->book_ordered,book->broken_aging,book->broken_manmade);
    printf("请输入增加的书籍数量:\n");
    int num = 0;
    scanf("%d",&num);
    book->book_sum += num;
    write_book_msg(book);
    print_sec("添加成功!\n",0.75);
}

void loss_book(void)
{
    printf("请输入您要报损的书号:\n");
    char ISBN[14];
    get_str(ISBN,sizeof(ISBN));
    if(13 != strlen(ISBN))
    {
        print_sec("位数输入错误!\n",0.75);
        return;
    }
    Book* book = read_book_msg(ISBN);
    if(NULL == book)
    {
        print_sec("没有该书号!\n",0.75);
        return;
    }
    printf("请选择损坏原因:\n");
    printf("1.自然损坏  2.人为损坏\n");
    bool aging_flag = false;                //false 自然损坏  true 人为损坏
    switch(get_cmd('1','2'))
	{
        case '1':aging_flag = false     ;break;
		case '2':aging_flag = true      ;break;                         
	}
    printf("请输入损坏数量:\n");
    int num = 0;
    scanf("%d",&num);
    book->book_sum -= num;
    if(aging_flag)
    {
        book->broken_manmade += num;
        write_book_msg(book);
        return;
    }
    book->broken_aging += num;
    
    write_book_msg(book);
}

bool bookfile_empty(const char* filename)               //检验书文件是否为存在
{
    char path[100] = "/home/coco/图书馆管理系统/book_data/";
    strcat(path,filename);
    FILE* rfp = fopen(path,"r");
    if(NULL == rfp)
    {
        return true;
    }
    fclose(rfp);
    return false;
}

void add_book_type_index(Book* book)
{
    book_type_index[book->type].sum++;
    if(book_type_index[book->type].sum >= book_type_index[book->type].cap)
    {
        book_type_index[book->type].cap *= 2;
        book_type_index[book->type].id = calloc(book_type_index[book->type].cap,sizeof(char*));
    }
    book_type_index[book->type].id[book_type_index[book->type].sum-1] = malloc(14);
    strcpy(book_type_index[book->type].id[book_type_index[book->type].sum-1],book->ISBN);
}

void delete_book_type_index(Book* book)
{
    if(1 == book_type_index[book->type].sum)
    {
        book_type_index[book->type].sum--;
        free(book_type_index[book->type].id[0]);
        return;
    }
    for(int i=0;i<book_type_index[book->type].sum;i++)
    {
        if(0 == strcmp(book_type_index[book->type].id[i],book->ISBN))
        {
            strcpy(book_type_index[book->type].id[i],book_type_index[book->type].id[book_type_index[book->type].sum-1]);
            free(book_type_index[book->type].id[book_type_index[book->type].sum-1]);
            book_type_index[book->type].sum--;
            return;
        }
    }
}

void add_book_key_index(Book* book)
{
    book_key_index[book->key].sum++;
    if(book_key_index[book->key].sum >= book_key_index[book->key].cap)
    {
        book_key_index[book->key].cap *= 2;
        book_key_index[book->key].id = calloc(book_key_index[book->key].cap,sizeof(char*));
    }
    book_key_index[book->key].id[book_key_index[book->key].sum-1] = malloc(14);
    strcpy(book_key_index[book->key].id[book_key_index[book->key].sum-1],book->ISBN);
}

void delete_book_key_index(Book* book)
{
    if(1 == book_key_index[book->key].sum)
    {
        book_key_index[book->key].sum--;
        free(book_key_index[book->key].id[0]);
        return;
    }
    for(int i=0;i<book_key_index[book->key].sum;i++)
    {
        if(0 == strcmp(book_key_index[book->key].id[i],book->ISBN))
        {
            strcpy(book_key_index[book->key].id[i],book_key_index[book->key].id[book_key_index[book->key].sum-1]);
            free(book_key_index[book->key].id[book_key_index[book->key].sum-1]);
            book_key_index[book->key].sum--;
            return;
        }
    }
}

void delete_all_order(const char* ISBN)
{
    DIR *pDir = NULL;
  	struct dirent * pEnt = NULL;
	pDir = opendir("/home/coco/图书馆管理系统/stu_data");
    while (1)
    {
      	pEnt = readdir(pDir);
    	if(pEnt != NULL)
    	{
     		if (pEnt->d_type == DT_REG)
      		{
                char filename[18];
                strcpy(filename,pEnt->d_name);
                char* tmp = filename;
                while('.' != *tmp)
                {
                    tmp++;
                }
                *tmp = '\0';
                Student* stu = read_stu(filename);
                delete_stu_order(stu,ISBN);
                free(stu);
      		}
    	}
     	else //没有子文件，跳出循环
     	{
     		break;
     	}
    }
	closedir(pDir);
}

void delete_stu_order(Student* stu,const char* ISBN)
{
    if(0 == stu->recond->order_sum)
    {
        return;
    }
    Recond_node* node = stu->recond->head_order->next;
    for(int i=0;i<stu->recond->order_sum;i++)
    {
        if(0 == strcmp(node->data,ISBN))
        {
            delete_node_recond(node);
            stu->recond->order_sum--;
            write_stu(stu);
            break;
        }
    }
}

void borrow_book(void)
{
    system("clear");
    printf("请输入学生学号(7位):\n");
    char id[8];
    get_str(id,sizeof(id));
    if(7 != strlen(id))
    {
        print_sec("学号位数错误!\n",0.75);
        return;
    }
    Student* stu = read_stu(id);
    if(NULL == stu)
    {
        print_sec("没有该学生!\n",0.75);
        return;
    }
    if(stu->recond->borrow_sum >= BORROW_MAX)           //判断学生的借书数量是否超过上限
    {
        print_sec("您借书数量已超过上限",0.75);
        return;
    }
    if(stu->recond->overdue_sum > 0)
    {
        print_sec("您有书已逾期,请先归回逾期书籍再借书!\n",0.75);
        return;
    }

    printf("是否借阅已预约书籍?\n");
    if(yes_or_no())
    {
        _borrow_order_book(stu);
        return;
    }
    _borrow_book(stu);
    free(stu);
}

void _borrow_book(Student* stu)
{
    do{
        system("clear");
        printf("请输入书号:\n");
        char ISBN[14];
        get_str(ISBN,sizeof(ISBN));
        Book* book = read_book_msg(ISBN);
        Recond_node* node = stu->recond->head_borrow->next;
        for(int i=0;i<stu->recond->borrow_sum;i++)              //判断该书是否已经被人借走
        {   
            if(0 == strcmp(node->data,book->ISBN))
            {
                print_sec("该书已被您借阅!\n",0.75);
                return;
            }
            node = node->next;
        }
        time_t current_time;
        book->book_sum--;
        book->book_borrowed++;
        stu->recond->borrow_sum++;
        add_node_recond(stu->recond->head_borrow,book->ISBN,time(&current_time));
        write_book_msg(book);
        write_stu(stu);
        write_time_msg(book->ISBN,stu->id);
        print_sec("借阅成功!\n",0.75);
        printf("是否继续借阅?\n");
    }while(yes_or_no());
}

void _borrow_order_book(Student* stu)
{
    system("clear");
    if(0 == stu->recond->order_sum)
    {
        print_sec("您没有预约书籍!\n",0.75);
        return;
    }
    printf("您预约的书有:\n");

    Recond_node* head = stu->recond->head_order;
    Recond_node* node = head->next;
    int sum = stu->recond->order_sum;
    time_t current_time;
    for(int i=0;i<sum;i++)
    {
        Book* book = read_book_msg(node->data);
        if(0 == book->book_sum)
        {
            printf("书号:%s 书名:%s 仓库没货!\n",book->ISBN,book->bookname);
            continue;
        }
        book->book_sum--;
        book->book_borrowed++;
        book->book_ordered--;
        stu->recond->borrow_sum++;
        stu->recond->order_sum--;
        add_node_recond(stu->recond->head_borrow,book->ISBN,time(&current_time));
        delete_node_recond(node);
        node = head->next;
        printf("书号:%s 书名:%s 借阅成功!\n",book->ISBN,book->bookname);
        write_stu(stu);
        write_book_msg(book);
        write_time_msg(book->ISBN,stu->id);
        free(book);
    }
    anykey_continue();
}

void write_time_msg(const char* ISBN,const char* id)
{
    char YMD[15] = {0};
    char HMS[10] = {0};
    char *cur_time = (char *)malloc(21*sizeof(char));
    struct tm* now_time;

    time_t current_time;
    time(&current_time);
    now_time = localtime(&current_time);

    strftime(YMD, sizeof(YMD), "%F ", now_time);
    strftime(HMS, sizeof(HMS), "%T", now_time);

    strcpy(cur_time, YMD);
    strncat(cur_time, HMS, 8);

    FILE* afp = fopen("borrow.txt","a");
    printf("%s\n",cur_time);
    fprintf(afp,"%s 学号:%s 书号:%s\n",cur_time,id,ISBN);
    free(cur_time);
    fclose(afp);
}

void repay_book(void)
{
    system("clear");
    printf("请输入学生学号(7位):\n");
    char id[8];
    get_str(id,sizeof(id));
    if(7 != strlen(id))
    {
        print_sec("学号位数错误!\n",0.75);
        return;
    }
    Student* stu = read_stu(id);
    if(NULL == stu)
    {
        print_sec("没有该学生!\n",0.75);
        return;
    }
    while(1)
    {
        printf("请输入书号:\n");
        char ISBN[14];
        get_str(ISBN,sizeof(ISBN));
        if(13 != strlen(ISBN))
        {
            printf("书号错误!\n");
        }
        else
        {
            Book* book = read_book_msg(ISBN);
            _repay_book(book,stu);
            free(book);
        }
        printf("是否继续还书?\n");
        if(!yes_or_no())
        {
            break;
        }
    }
    free(stu);
}

void _repay_book(Book* book,Student* stu)
{
    printf("书籍是否损坏?\n");
    bool is_broken = false;
    if(yes_or_no())
    {
        printf("请支付三倍书价%.2f\n",book->book_price*3);
         printf("您的支付宝:\n");
        char phone[20];
        get_str(phone,sizeof(phone));
        print_sec("支付完成!",0.75);
        is_broken = true;
    }
    if(stu->recond->overdue_sum > 0)                            //逾期还书缴费
    {
        Recond_node* node = stu->recond->head_overdue->next;
        for(int i=0;i<stu->recond->overdue_sum;i++)
        {
            if(0 == strcmp(node->data,book->ISBN))
            {
                printf("请缴纳5元逾期费\n");
                printf("您的支付宝:\n");
                char phone[20];
                get_str(phone,sizeof(phone));
                delete_node_recond(node);
                stu->recond->overdue_sum--;
                if(is_broken)
                {
                    book->broken_manmade++;
                }
                else
                {
                    book->book_sum++;
                }
                book->book_borrowed--;
                stu->recond->repay_sum++;
                time_t current_time;
                add_node_recond(stu->recond->head_repay,book->ISBN,time(&current_time));
                write_book_msg(book);
                write_stu(stu);
                print_sec("归还成功!\n",0.75);
                return;
            }
            node = node->next;
        }
    }
    if(stu->recond->borrow_sum > 0)
    {
        Recond_node* node = stu->recond->head_borrow->next;
        for(int i=0;i<stu->recond->borrow_sum;i++)
        {
            if(0 == strcmp(node->data,book->ISBN))
            {
                delete_node_recond(node);
                stu->recond->borrow_sum--;
                book->book_borrowed--;

                book->book_sum++;
                stu->recond->repay_sum++;
                time_t current_time;
                add_node_recond(stu->recond->head_repay,book->ISBN,time(&current_time));
                write_book_msg(book);
                write_stu(stu);
                print_sec("归还成功!\n",0.75);
                return;
            }
            node = node->next;
        }
    }
    print_sec("您未借过这本书,请联系工作人员!",3);
}

void show_overdue(void)
{
    system("clear");
    DIR *pDir = NULL;
  	struct dirent * pEnt = NULL;
	pDir = opendir("/home/coco/图书馆管理系统/stu_data");
    while (1)
    {
      	pEnt = readdir(pDir);
    	if(pEnt != NULL)
    	{
     		if (pEnt->d_type == DT_REG)
      		{
                Student* stu = read_stu(pEnt->d_name);
                if(stu->recond->overdue_sum > 0)
                {
                    printf("学号:%s 逾期:\n",stu->id);
                    Recond_node* node = stu->recond->head_overdue->next;
                    for(int i=0;i<stu->recond->overdue_sum;i++)
                    {
                        printf("书号:%s ",node->data);
                        show_time_msg(node->time_sec);
                        node = node->next;
                    }
                }
                free(stu);
      		}
    	}
        else
            {
                break;
            }
    }
	closedir(pDir);
    anykey_continue();
}

void sigalrm(int signum)
{
    overdue();
    alarm(12);             //半天检测一次
}

void overdue(void)
{
    time_t current_time;
    DIR *pDir = NULL;
  	struct dirent * pEnt = NULL;
	pDir = opendir("/home/coco/图书馆管理系统/stu_data");
    while (1)
    {
      	pEnt = readdir(pDir);
    	if(pEnt != NULL)
    	{
     		if (pEnt->d_type == DT_REG)
      		{
                Student* stu = read_stu(pEnt->d_name);
                Recond_node* node = stu->recond->head_borrow->next;
                for(int i=0;i<stu->recond->borrow_sum;i++)
                {
                    if(time(&current_time) - node->time_sec > 30)
                    {
                        Recond_node* tmp = node;
                        node = node->next;
                        stu->recond->borrow_sum--;
                        stu->recond->overdue_sum++;
                        add_node_recond(stu->recond->head_overdue,tmp->data,time(&current_time));
                        delete_node_recond(tmp);
                        continue;
                    }
                    node = node->next;
                }
                write_stu(stu);
                free(stu);
      		}
            else
            {
                break;
            }
    	}
    }
	closedir(pDir);
}